package com.example.demo.listener;

import com.example.demo.common.Func;
import com.example.demo.common.constant.RedisKey;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

/**
 * 初始化加载也可以去掉，改为每次修改提交用户信息时，都将redis中相应的用户token记录删除
 * 1、redis中的userRole构成：key为role_用户ID，value为角色名称、角色权限串
 * 2、redis中的userToken构成：key为token_用户ID，value为用户ID、姓名、时间值、UUID/ULID（同时将其返回前端）
 * 3、redis中的userRole与userToken的过期时间设为30分钟
 * 4、身份校验时，
 * 1）若token值不存在，则提示【未正常登录】或【过期了，请重新登录】
 * 2）若token值不一致，则提示【已在别处登录】
 * 3）若token值相同，重新设置userRole与userToken的过期时间为30分钟
 *
 * 注：redis键名统一格式：logier:name:{id}、logier:role:{id}、logier:time:{id}、logier:token:{id}
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class InitLoadListener implements ApplicationListener<ApplicationStartedEvent> {
    private final RedisTemplate<String, String> redis;

    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        try {
            /*MPJLambdaWrapper<User> query = new MPJLambdaWrapper<>();
            query.select(User::getUserid, User::getUsername, User::getPassword);
            query.eq(User::getIsuse, "1");

            List<Map<String, Object>> list = userMapper.selectMaps(query);

            boolean result = false;
            for (Map<String, Object> info : list) {
                String key = "token_" + info.get("userid").toString();
                redis.opsForValue().set(key, info.toString(), 1200, TimeUnit.SECONDS);

                result = true;
            }

            if (result) {
                log.info("init load data success!");
            }
            else {
                log.error("load data is empty");
            }*/

            //redis.opsForValue().set(RedisKey.CONFIG_WHITELIST_LOAD, "true", 1, TimeUnit.DAYS);
            initWhitelist();

            log.info("init load data success!");
        }
        catch (Exception ex) {
            log.error("load data error! please check the system code");
        }
    }

    private void initWhitelist() throws FileNotFoundException, UnsupportedEncodingException {
        // 加载配置文件里的白名单（/file/config/whitelist.txt）
        // 1、清空旧的白名单
        redis.delete(RedisKey.CONFIG_WHITELIST_LIST);

        // 2、加载新的白名单，有效期1天
        String filePath = Func.getRootPath() + "/file/config/whitelist.txt";
        Scanner scanner = new Scanner(new BufferedReader(new FileReader(filePath)));
        scanner.useDelimiter("/n");
        while (scanner.hasNext()) {
            String line = URLDecoder.decode(scanner.nextLine(), "utf8");
            if (!line.contains("key:")) {
                redis.opsForList().rightPush(RedisKey.CONFIG_WHITELIST_LIST, line);
            }
        }
        scanner.close();
        redis.expire(RedisKey.CONFIG_WHITELIST_LIST, 1, TimeUnit.DAYS);
        log.info("the whiteList is {}", redis.opsForList().range(RedisKey.CONFIG_WHITELIST_LIST, 0, -1));

        // 3、设置：重置白名单的加载标识为false，即：不必加载
        redis.opsForValue().set(RedisKey.CONFIG_WHITELIST_LOAD, "false", 1, TimeUnit.DAYS);
    }

}
